#!/usr/bin/python -S
"""
params_test.py: Tests for params.py

Longer description here.
"""

__author__ = 'Andy Chu'


import os
import sys
import unittest

if __name__ == '__main__':
  sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), '../..'))

import params  # module under test


class ParamsTest(unittest.TestCase):
  def setUp(self):
    pass

  def tearDown(self):
    pass

  def testConvertTypes(self):
    definition = [params.OptionalBoolean('use')]
    self.assertEqual(
        params.ConvertTypes({'use': 'true'}, definition),
        {'use': True})
    self.assertEqual(
        params.ConvertTypes({'use': False}, definition),
        {'use': False})
    self.assertRaises(params.CannotConvertType,
        params.ConvertTypes, {'use': 'blah'}, definition)

    definition = [params.OptionalInteger('num')]
    self.assertEqual(
        params.ConvertTypes({'num': '1'}, definition),
        {'num': 1})
    self.assertRaises(params.CannotConvertType,
        params.ConvertTypes, {'num': 'blah'}, definition)

    definition = [params.OptionalString('foo')]
    self.assertEqual(
        params.ConvertTypes({'foo': 'bar'}, definition),
        {'foo': 'bar'})

  def testConvertTypes_Required(self):
    definition = [params.RequiredString('foo')]
    self.assertEqual(
        params.ConvertTypes({'foo': 'bar', 'extra': 'noshow'}, definition),
        {'foo': 'bar'})

  def testConvertTypes_List(self):
    return  # disabled by lack of 'parsing' module
    definition = [params.RepeatedStrings('argv')]
    self.assertEqual(
        params.ConvertTypes({'argv': 'foo bar'}, definition),
        {'argv': ['foo', 'bar']})

  def testConvertTypes_Undeclared(self):
    return  # disabled by lack of 'parsing' module
    definition = [
        params.RepeatedStrings('argv'),
        params.UNDECLARED,
        ]
    self.assertEqual(
        params.ConvertTypes(
            {'argv': 'f b', 'bar': 'undeclared', 'foo': '1'}, definition),
        { 'argv': ['f', 'b'],
          'undeclared.bar': 'undeclared',
          'undeclared.foo': '1'}
        )

  def testValidateParams(self):
    definition = [params.OptionalInteger('num', minval=3)]
    self.assertRaises(params.IntegerOutOfRange,
        params.ValidateParamValues, {'num': 1}, definition)

    definition = [params.RequiredString('foo', choices=['spam', 'eggs'])]
    self.assertRaises(params.InvalidInput,
        params.ValidateParamValues, {'foo': 'yo'}, definition)
    params.ValidateParamValues({'foo': 'spam'}, definition)

  def assertRecordEqualsDictionary(self, record, dictionary):
    # TEMP HACK
    r = params.ToKeywordArgs(dictionary)
    self.assertEqual(record, r)

  def testMakeRecord(self):
    param_definition = [
        params.RequiredString('page-name'),
        params.OptionalString(
            'string', default='default',
            choices=['default', 'Choice1', 'Choice2']),

        params.RequiredInteger('n', minval=2, maxval=100),
        params.OptionalInteger('num-cols', default=1),

        params.OptionalBoolean('stylesheet', default=False),
        ]

    self.assertRaises(
        params.RequiredParameterMissing,
        params.MakeRecord, {}, param_definition)

    typed = params.MakeRecord(
        {'page-name': 'Front_Page', 'n': '36', 'extra-crap': 'foo'},
        param_definition)
    self.assertRecordEqualsDictionary(
        typed,
        { 'page-name': 'Front_Page', 'stylesheet': False, 'num-cols': 1,
          'string': 'default', 'n': 36})

    self.assertRaises(
        params.CannotConvertType,
        params.MakeRecord, 
        {'page-name': 'Front_Page', 'n': 'not an int'}, param_definition)

    self.assertRaises(
        params.CannotConvertType,
        params.MakeRecord, 
        {'page-name': 'Front_Page', 'n': '36', 'stylesheet': 'not boolean'},
        param_definition)

    self.assertRaises(
        params.IntegerOutOfRange,
        params.MakeRecord, 
        {'page-name': 'Front_Page', 'n': '105'},
        param_definition)

    self.assertRaises(
        params.IntegerOutOfRange,
        params.MakeRecord, 
        {'page-name': 'Front_Page', 'n': '1'},
        param_definition)


class FormTest(unittest.TestCase):

  def testMakeFormFragment(self):
    return  # disabled by lack of 'parsing' module
    definition = [
        params.RequiredString('foo'),
        params.OptionalBoolean('strict', default=True),
        ]
    print params.MakeFormFragment('test', definition)


if __name__ == '__main__':
  unittest.main()
